//
//  HWDataBaseManager.swift
//  HWanGame
//
//  Created by 王昌健 on 2023/12/13.
//  Copyright © 2023 94hwan. All rights reserved.
//

import UIKit

class HWDataBaseManager: NSObject {
    // 单例模式
    @objc static let defaultManger = HWDataBaseManager()
    
    typealias successBlock = () ->Void
    typealias failBlock = () ->Void
    
    private var tableName:String?
    
    // 创建数据库
    lazy var fmdb:FMDatabase = {
        let path = NSHomeDirectory().appending("/Documents/HWanGame.db")
        let db = FMDatabase(path: path)
        return db
    }()
//    integer primary key
    // 创建表
    func creatTable(tableName:String) -> Void {
        fmdb.open()
        self.tableName = tableName
        let creatSql = "create table if not exists \(tableName) (id integer primary key autoincrement,userId text,appId,model BLOB)"
        let result = fmdb.executeUpdate(creatSql, withArgumentsIn:[])
        if result{
            print("创建表成功")
        }
    }
    
    //删除表
    @objc func dropTable() -> Void {
        let sql = "drop table if exists " + (tableName ?? "")
        let result = fmdb.executeUpdate(sql, withArgumentsIn:[])
        if result{
            print("删除表成功")
        }
    }
    
    //插入数据
    func insert(appId:String,model:NSObject, successBlock: successBlock, failBlock: failBlock) -> Void {
        print(NSHomeDirectory())

        let modelData = try! NSKeyedArchiver.archivedData(withRootObject: model, requiringSecureCoding: false)
        let insertSql = "insert into " + tableName! + " (userId,appId,model) values('\(HWLocallyStoredData.getLoginUserID())',\(appId),?)"

        do {
            try fmdb.executeUpdate(insertSql, values: [modelData])
            successBlock()
        } catch {
            print(fmdb.lastError())
            failBlock()
        }
    }
    
//    //更新数据
//    func update(model:NSObject,uid:Int32, successBlock: successBlock, failBlock: failBlock) -> Void {
//        
//        let modelData = try! NSKeyedArchiver.archivedData(withRootObject: model, requiringSecureCoding: false)
//        
//        let updateSql = "update " + tableName! + " set model = ? where id = ?"
//        
//        do {
//            try fmdb.executeUpdate(updateSql, values: [modelData, uid])
//            successBlock()
//        } catch {
//            print(fmdb.lastError())
//            failBlock()
//        }
//    }
    
    func deleteWithSql(sql:String, successBlock: successBlock, failBlock: failBlock) -> Void {
            
        let deleteSql = "delete from " + tableName! + " where " + sql
        do {
            try fmdb.executeUpdate(deleteSql, values: nil)
            print(fmdb.lastError())
        } catch {
            print(fmdb.lastError())
        }
    }
    
    //删除数据
    func delete(appId:String, successBlock: successBlock, failBlock: failBlock) -> Void {
            
        let deleteSql = "delete from " + tableName! + " where appId = ? and userId = '\(HWLocallyStoredData.getLoginUserID())'"
        do {
            try fmdb.executeUpdate(deleteSql, values: [Int32(appId) as Any])
            print(fmdb.lastError())
        } catch {
            print(fmdb.lastError())
        }
    }
    
    //查询全部数据
    func selectAll() -> [NSObject] {
        var tmpArr = [NSObject]()
        let selectSql = "select * from " + tableName! + " where userId = '\(HWLocallyStoredData.getLoginUserID())' order by id desc"
        
        do {
            let rs = try fmdb.executeQuery(selectSql, values:nil)
            while rs.next() {
                var model = NSObject()
                let modelData  = rs.data(forColumn:"model")
                let id = rs.int(forColumn: "id")
                model = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(modelData!) as! NSObject
                model.wd_fmdb_id = Int32(id)
                tmpArr.append(model)
            }
        } catch {
            print(fmdb.lastError())
        }
        return tmpArr
    }
}

private var wd_id_key: String = "key"

extension NSObject {
    public var wd_fmdb_id:Int32? {
        get {
            return (objc_getAssociatedObject(self, &wd_id_key) as? Int32)
        } set(newValue) {
            objc_setAssociatedObject(self, &wd_id_key, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
        }
    }
}
